package cn.iocoder.yudao.module.acm.service.onboardproduceplan;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.acm.controller.admin.onboardproduceplan.vo.OnboardProducePlanPageReqVO;
import cn.iocoder.yudao.module.acm.controller.admin.onboardproduceplan.vo.OnboardProducePlanSaveReqVO;
import cn.iocoder.yudao.module.acm.controller.app.onboardsupplyplan.vo.AppOnboardProducePlanPageReqVO;
import cn.iocoder.yudao.module.acm.controller.app.onboardsupplyplan.vo.AppOnboardProducePlanRespVO;
import cn.iocoder.yudao.module.acm.controller.app.onboardsupplyplan.vo.AppSupplyPlanDetailRespVO;
import cn.iocoder.yudao.module.acm.dal.dataobject.onboardproduceplan.OnboardProducePlanDO;
import cn.iocoder.yudao.module.acm.dal.dataobject.onboardsupply.OnboardSupplyDO;
import cn.iocoder.yudao.module.acm.dal.dataobject.supplyplandetail.SupplyPlanDetailDO;
import cn.iocoder.yudao.module.acm.dal.dataobject.tablewareplandetail.TablewarePlanDetailDO;
import cn.iocoder.yudao.module.acm.dal.dataobject.textileplandetail.TextilePlanDetailDO;
import cn.iocoder.yudao.module.acm.dal.mysql.onboardproduceplan.OnboardProducePlanMapper;
import cn.iocoder.yudao.module.acm.dal.mysql.onboardsupply.OnboardSupplyMapper;
import cn.iocoder.yudao.module.acm.dal.mysql.supplyplandetail.SupplyPlanDetailMapper;
import cn.iocoder.yudao.module.acm.dal.mysql.tablewareplandetail.TablewarePlanDetailMapper;
import cn.iocoder.yudao.module.acm.dal.mysql.textileplandetail.TextilePlanDetailMapper;
import cn.iocoder.yudao.module.acm.enums.ACMCabinClassEnum;
import cn.iocoder.yudao.module.acm.enums.ACMSupplyStandardEnum;
import cn.iocoder.yudao.module.pplan.enums.PPlanAirlineIdEnum;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.acm.enums.ErrorCodeConstants.ONBOARD_PRODUCE_PLAN_NOT_EXISTS;

/**
 * 航机管理-机供品生产计划 Service 实现类
 *
 * @author yisla
 */
@Service
@Validated
public class OnboardProducePlanServiceImpl implements OnboardProducePlanService {

    @Resource
    private OnboardProducePlanMapper onboardProducePlanMapper;
    @Resource
    private OnboardSupplyMapper onboardSupplyMapper;
    @Resource
    private SupplyPlanDetailMapper supplyPlanDetailMapper;
    @Resource
    private TablewarePlanDetailMapper tablewarePlanDetailMapper;
    @Resource
    private TextilePlanDetailMapper textilePlanDetailMapper;

    @Override
    public Long createOnboardProducePlan(OnboardProducePlanSaveReqVO createReqVO) {
        // 插入
        OnboardProducePlanDO onboardProducePlan = BeanUtils.toBean(createReqVO, OnboardProducePlanDO.class);
        onboardProducePlanMapper.insert(onboardProducePlan);
        // 返回
        return onboardProducePlan.getId();
    }

    @Override
    public void updateOnboardProducePlan(OnboardProducePlanSaveReqVO updateReqVO) {
        // 校验存在
        validateOnboardProducePlanExists(updateReqVO.getId());
        // 更新
        OnboardProducePlanDO updateObj = BeanUtils.toBean(updateReqVO, OnboardProducePlanDO.class);
        onboardProducePlanMapper.updateById(updateObj);
    }

    @Override
    public void deleteOnboardProducePlan(Long id) {
        // 校验存在
        validateOnboardProducePlanExists(id);
        // 删除
        onboardProducePlanMapper.deleteById(id);
    }

    @Override
        public void deleteOnboardProducePlanListByIds(List<Long> ids) {
        // 校验存在
        validateOnboardProducePlanExists(ids);
        // 删除
        onboardProducePlanMapper.deleteByIds(ids);
        }

    private void validateOnboardProducePlanExists(List<Long> ids) {
        List<OnboardProducePlanDO> list = onboardProducePlanMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(ONBOARD_PRODUCE_PLAN_NOT_EXISTS);
        }
    }

    private void validateOnboardProducePlanExists(Long id) {
        if (onboardProducePlanMapper.selectById(id) == null) {
            throw exception(ONBOARD_PRODUCE_PLAN_NOT_EXISTS);
        }
    }

    @Override
    public OnboardProducePlanDO getOnboardProducePlan(Long id) {
        return onboardProducePlanMapper.selectById(id);
    }

    @Override
    public PageResult<OnboardProducePlanDO> getOnboardProducePlanPage(OnboardProducePlanPageReqVO pageReqVO) {
        return onboardProducePlanMapper.selectPage(pageReqVO);
    }

    // --- APP----------
    @Override
    public AppOnboardProducePlanRespVO appGetOnboardProducePlan(Long id) {
        OnboardProducePlanDO supplyPlanDO = onboardProducePlanMapper.selectById(id);
        AppOnboardProducePlanRespVO onboardSupplyPlanRespVO = BeanUtils.toBean(supplyPlanDO, AppOnboardProducePlanRespVO.class);

        //查询机供品详细信息
        List<SupplyPlanDetailDO> detailDOS = supplyPlanDetailMapper.selectList(SupplyPlanDetailDO::getSupplyPlanId, supplyPlanDO.getOnboardId());
        if (CollUtil.isNotEmpty(detailDOS)) {
            // 查询机供品分类信息
            List<Long> supplyIds = convertList(detailDOS, SupplyPlanDetailDO::getSupplyId).stream().distinct().collect(Collectors.toList());
            List<OnboardSupplyDO> supplyDOS = onboardSupplyMapper.selectByIds(supplyIds);
            Map<Long, OnboardSupplyDO> supplyMap = CollectionUtils.convertMap(supplyDOS, OnboardSupplyDO::getId);
            // 转换
            List<AppSupplyPlanDetailRespVO> respVOS = BeanUtils.toBean(detailDOS, AppSupplyPlanDetailRespVO.class, respVo -> {
                MapUtils.findAndThen(supplyMap, Long.parseLong(respVo.getSupplyId()), supply->{
                    respVo.setSupplyName(supply.getName());
                    respVo.setSupplyStandard(ACMSupplyStandardEnum.getDesc(supply.getStandard()));
                });
            });
            Map<String, List<AppSupplyPlanDetailRespVO>> collect = respVOS.stream().collect(Collectors.groupingBy(AppSupplyPlanDetailRespVO::getCabainClass));
            onboardSupplyPlanRespVO.setFrontSupplys(collect.get(ACMCabinClassEnum.CABIN_CLASS_ENUM_1.getCode()));
            onboardSupplyPlanRespVO.setMiddleSupplys(collect.get(ACMCabinClassEnum.CABIN_CLASS_ENUM_2.getCode()));
            onboardSupplyPlanRespVO.setRearSupplys(collect.get(ACMCabinClassEnum.CABIN_CLASS_ENUM_3.getCode()));
        }

        //查询服务用具详细信息
        List<TablewarePlanDetailDO> twDetailDOS = tablewarePlanDetailMapper.selectList(TablewarePlanDetailDO::getTablewarePlanId, supplyPlanDO.getServiceId());
        if (CollUtil.isNotEmpty(twDetailDOS)) {
            // 查询服务用具分类信息
            List<Long> supplyIds = convertList(twDetailDOS, TablewarePlanDetailDO::getSupplyId).stream().distinct().collect(Collectors.toList());
            List<OnboardSupplyDO> supplyDOS = onboardSupplyMapper.selectByIds(supplyIds);
            Map<Long, OnboardSupplyDO> supplyMap = CollectionUtils.convertMap(supplyDOS, OnboardSupplyDO::getId);
            // 转换
            List<AppSupplyPlanDetailRespVO> respVOS = BeanUtils.toBean(twDetailDOS, AppSupplyPlanDetailRespVO.class, respVo -> {
                MapUtils.findAndThen(supplyMap, Long.parseLong(respVo.getSupplyId()), supply->{
                    respVo.setSupplyName(supply.getName());
                    respVo.setSupplyStandard(ACMSupplyStandardEnum.getDesc(supply.getStandard()));
                });
            });
            Map<String, List<AppSupplyPlanDetailRespVO>> collect = respVOS.stream().collect(Collectors.groupingBy(AppSupplyPlanDetailRespVO::getCabainClass));
            onboardSupplyPlanRespVO.setFrontServices(collect.get(ACMCabinClassEnum.CABIN_CLASS_ENUM_1.getCode()));
            onboardSupplyPlanRespVO.setMiddleServices(collect.get(ACMCabinClassEnum.CABIN_CLASS_ENUM_2.getCode()));
            onboardSupplyPlanRespVO.setRearServices(collect.get(ACMCabinClassEnum.CABIN_CLASS_ENUM_3.getCode()));
        }
        //查询纺织品详细信息
        List<TextilePlanDetailDO> textileDetailDOS = textilePlanDetailMapper.selectList(TextilePlanDetailDO::getTextilePlanId, supplyPlanDO.getTextileId());
        if (CollUtil.isNotEmpty(textileDetailDOS)) {
            // 查询纺织品分类信息
            List<Long> supplyIds = convertList(textileDetailDOS, TextilePlanDetailDO::getSupplyId).stream().distinct().collect(Collectors.toList());
            List<OnboardSupplyDO> supplyDOS = onboardSupplyMapper.selectByIds(supplyIds);
            Map<Long, OnboardSupplyDO> supplyMap = CollectionUtils.convertMap(supplyDOS, OnboardSupplyDO::getId);
            // 转换
            List<AppSupplyPlanDetailRespVO> respVOS = BeanUtils.toBean(textileDetailDOS, AppSupplyPlanDetailRespVO.class, respVo -> {
                MapUtils.findAndThen(supplyMap, Long.parseLong(respVo.getSupplyId()), supply->{
                    respVo.setSupplyName(supply.getName());
                    respVo.setSupplyStandard(ACMSupplyStandardEnum.getDesc(supply.getStandard()));
                });
            });
            Map<String, List<AppSupplyPlanDetailRespVO>> collect = respVOS.stream().collect(Collectors.groupingBy(AppSupplyPlanDetailRespVO::getCabainClass));
            onboardSupplyPlanRespVO.setFrontTextiles(collect.get(ACMCabinClassEnum.CABIN_CLASS_ENUM_1.getCode()));
            onboardSupplyPlanRespVO.setMiddleTextiles(collect.get(ACMCabinClassEnum.CABIN_CLASS_ENUM_2.getCode()));
            onboardSupplyPlanRespVO.setRearTextiles(collect.get(ACMCabinClassEnum.CABIN_CLASS_ENUM_3.getCode()));
        }
        return onboardSupplyPlanRespVO;
    }

    @Override
    public PageResult<AppOnboardProducePlanRespVO> appGetOnboardProducePlanPage(AppOnboardProducePlanPageReqVO pageReqVO) {
        PageResult<OnboardProducePlanDO> doPageResult = onboardProducePlanMapper.appSelectPage(pageReqVO);
        return new PageResult<>(buildDetailList(doPageResult.getList()), doPageResult.getTotal());
    }
    private List<AppOnboardProducePlanRespVO> buildDetailList(List<OnboardProducePlanDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        return BeanUtils.toBean(list, AppOnboardProducePlanRespVO.class, respVO -> {
            respVO.setAirlineCompName(PPlanAirlineIdEnum.getDesc(respVO.getAirlineComp()));
            respVO.setTotalQty(respVO.getFrontCabinQty()+respVO.getMiddleCabinQty()+respVO.getRearCabinQty());
        });
    }

}